package cz.cacek.ebook.packager;

import j2me.util.ArrayList;
import j2me.util.List;

import java.awt.AWTEvent;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;

import cz.cacek.ebook.Utils;

//import cz.cacek.ebook.Utils;

/**
 * New Swing UI for EBookME
 *
 * @author Josef Cacek [josef.cacek (at) gmail.com]
 * @author $Author: kwart $
 * @version $Revision: 1.9 $
 * @created $Date: 2007/08/31 12:32:53 $
 */
public class NewEbGui extends javax.swing.JPanel {

	private static final long serialVersionUID = 105139301555996L;

	protected final static PropertyProvider props = PropertyProvider
			.getInstance();

	protected final static ResourceProvider res = ResourceProvider
			.getInstance();

	protected final JFileChooser fOpenFileChooser = new JFileChooser(".");
	protected final JFileChooser fJadFileChooser = new JFileChooser(".");

	protected final JFileChooser fProfileChooser = new JFileChooser(".");

	protected ImageChooser imageChooser = new ImageChooser();

	protected DefaultListModel listModel = new DefaultListModel();
	protected Set idSet = new HashSet();
	protected int bookNr = 1;
	protected String bookId = null;
	protected int oldIdx = -1;
	protected boolean bookChanged = false;
	protected transient PrintStream logStream;
	protected boolean bookListListenerEnabled = true;

	protected DocumentListener bookChangeListener = new DocumentListener() {
		public void changedUpdate(DocumentEvent e) {
			bookChangedEvent();
		}

		public void insertUpdate(DocumentEvent e) {
			bookChangedEvent();
		}

		public void removeUpdate(DocumentEvent e) {
			bookChangedEvent();
		}
	};

	protected void runEmulator() {
		try {
			Class.forName("org.microemu.app.Main");
			MicroEmulatorBridge.run(props.getProperty(Constants.PROP_OUT)
					+ ".jad");
		} catch (Throwable e) {
		}
	}

	/** Creates new form NewEbGui */
	public NewEbGui() {
		initComponents();

		final class JadFileFilter extends FileFilter {
			public boolean accept(File f) {
				return f.isDirectory()
						|| f.getName().toUpperCase().endsWith(".JAD");
			}

			public String getDescription() {
				return "Java ME application description (.jad)";
			}

		}

		final JadFileFilter tmpJadFF = new JadFileFilter();
		fJadFileChooser.addChoosableFileFilter(tmpJadFF);
		fJadFileChooser.setAcceptAllFileFilterUsed(false);

		bookName.getDocument().addDocumentListener(bookChangeListener);
		description.getDocument().addDocumentListener(bookChangeListener);
		bookTextArea.getDocument().addDocumentListener(bookChangeListener);
		bookIdText.getDocument().addDocumentListener(bookChangeListener);
		saveTextField.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				saveTextFieldChange();
			}

			public void insertUpdate(DocumentEvent e) {
				saveTextFieldChange();
			}

			public void removeUpdate(DocumentEvent e) {
				saveTextFieldChange();
			}
		});

		setLabels();
		setAdvancedEnabled();
		fillCharsets();
		bookList.setModel(listModel);
		partSizeText.setText(props.getProperty(Constants.PROP_PARTSIZE));
		logStream = new PrintStream(new JTextAreaStream(logTextArea));
		bookList.setTransferHandler(new BookTransferHandler(this));
	}

	protected void saveTextFieldChange() {
		saveTextField
				.setBackground(saveTextField.getText().length() > 0 ? bookList
						.getBackground() : Color.RED);
		checkSaveBtn();
	}

	/** sets localized labels */
	private void setLabels() {
		lblCharset.setText(res.get("gui.label.encoding"));
		lblBufferSize.setText(res.get("gui.label.partsize"));
		lblBookName.setText(res.get("gui.label.textname"));
		lblDescription.setText(res.get("gui.label.textdescription"));
		lblText.setText(res.get("gui.label.text"));
		lblWelcomeScreen.setText(res.get("gui.label.splashscreen"));
		lblOutFile.setText(res.get("gui.label.outprefix"));

		autoformatCb.setText(res.get("gui.label.autoformat"));
		advancedCb.setText(res.get("gui.label.advanced"));
		advancedCb.setToolTipText(res.get("gui.tooltip.advanced"));
		rightToLeftCb.setText(res.get("gui.label.right"));
		rightToLeftCb.setToolTipText(res.get("gui.tooltip.right"));

		addBtn.setToolTipText(res.get("gui.tooltip.btn.add"));
		deleteBtn.setToolTipText(res.get("gui.tooltip.btn.delete"));
		upBtn.setToolTipText(res.get("gui.tooltip.btn.up"));
		downBtn.setToolTipText(res.get("gui.tooltip.btn.down"));
		fileButton.setToolTipText(res.get("gui.tooltip.btn.openbook"));
		saveChangesBtn.setToolTipText(res.get("gui.tooltip.btn.savechanges"));
		saveBtn.setToolTipText(res.get("gui.tooltip.btn.createjar"));
		defaultSplashBtn.setToolTipText(res.get("gui.tooltip.btn.defsplash"));

		boooksPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.books")));
		detailsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.details")));
		libPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.library")));
		advancedPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder(res.get("gui.panel.advanced")));
		outPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.out")));

		outFileBtn.setText(res.get("gui.btn.chooseFile"));
		splashBtn.setText(res.get("gui.btn.chooseFile"));
		saveBtn.setText(res.get("gui.btn.createJar"));
	}

	protected void bookChangedEvent() {
		if (!bookChanged) {
			detailsPanel.setBorder(javax.swing.BorderFactory
					.createTitledBorder(res.get("gui.panel.details") + " *"));
		}
		String id = this.bookIdText.getText();
		boolean shouldSaveChange = true;
		if (id == null || !this.isValidId(id)) {
			shouldSaveChange = false;
			bookIdText.setBackground(Color.RED);
		} else {
			bookIdText.setBackground(description.getBackground());
		}

		final String tmpId = shouldSaveChange ? id : Utils
				.createIdFromName(bookName.getText());
		if (bookName.getText() == null || "".equals(bookName.getText().trim())
				|| (idSet.contains(tmpId) && !tmpId.equals(bookId))) {

			bookName.setBackground(Color.RED);
			shouldSaveChange = false;
		} else {
			bookName.setBackground(description.getBackground());
		}
		saveChangesBtn.setEnabled(shouldSaveChange);

		bookChanged = true;
	}

	/** fills charset combobox with available character encodings */
	private void fillCharsets() {
		charsetCombo.removeAllItems();
		List itemList = new ArrayList();
		/* get encoding list start */
		{
			try {
				itemList.add(System.getProperty("file.encoding"));
			} catch (Exception e) {
				e.printStackTrace();
				// it's probably running from applet :-) - we don't have
				// permissions
				// to read system properties
			}

			String[] dArr = new String[] { "UTF-8", "ISO-8859-1", "ASCII" };
			for (int i = 0; i < dArr.length; i++) {
				String c = dArr[i];
				if (!itemList.contains(c)) {
					itemList.add(c);
				}
			}

			try {
				Map tmpCharsets = (Map) Class.forName(
						"java.nio.charset.Charset").getMethod(
						"availableCharsets", null).invoke(null, null);
				for (Iterator it = tmpCharsets.values().iterator(); it
						.hasNext();) {
					Object charset = it.next();
					String tmpName = (String) Class.forName(
							"java.nio.charset.Charset").getMethod(
							"displayName", null).invoke(charset, null);
					if (!itemList.contains(tmpName)) {
						itemList.add(tmpName);
					}
					// charsetCombo.addItem(tmpName);
				}
			} catch (Exception e) {
				e.printStackTrace();

				String[] charsetArr = new String[] { "ISO-8859-1",
						"ISO-8859-2", "ISO-8859-3", "ISO-8859-3", "ISO-8859-4",
						"ISO-8859-5", "ISO-8859-6", "ISO-8859-7",
						"windows-1250", "windows-1251", "windows-1252",
						"windows-1253", "windows-1257", "MacCentralEurope",
						"KOI8" };
				for (int i = 0; i < charsetArr.length; i++) {
					String c = charsetArr[i];
					if (!itemList.contains(c)) {
						itemList.add(c);
					}
				}

			}

		}
		/* get encoding list end. */

		ComboBoxModel model = new DefaultComboBoxModel(itemList.toArray());

		charsetCombo.setModel(model);
	}

	/** enables or disables components on advanced panel */
	private void setAdvancedEnabled() {
		final boolean tmpEnabled = advancedCb.isSelected();
		autoformatCb.setEnabled(tmpEnabled);
		partSizeText.setEnabled(tmpEnabled);
		charsetCombo.setEnabled(tmpEnabled);
		rightToLeftCb.setEnabled(tmpEnabled);

		lblBufferSize.setEnabled(tmpEnabled);
		lblCharset.setEnabled(tmpEnabled);
	}

	protected void alert(String message) {
		logStream
				.println(res.get("gui.status.error", new String[] { message }));
	}

	// GEN-BEGIN:initComponents
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {
		java.awt.GridBagConstraints gridBagConstraints;

		jMenuBar1 = new javax.swing.JMenuBar();
		jMenu1 = new javax.swing.JMenu();
		jMenuItemOfSaveProfile = new javax.swing.JMenuItem();
		jMenuItemOfLoadProfile = new javax.swing.JMenuItem();
		jMenu2 = new javax.swing.JMenu();
		detailsPanel = new javax.swing.JPanel();
		lblBookName = new javax.swing.JLabel();
		bookName = new javax.swing.JTextField();
		description = new javax.swing.JTextField();
		lblDescription = new javax.swing.JLabel();
		lblText = new javax.swing.JLabel();
		jScrollPaneOfBookText = new javax.swing.JScrollPane();
		bookTextArea = new javax.swing.JTextArea();
		saveChangesBtn = new javax.swing.JButton();
		fileButton = new javax.swing.JButton();
		lblBookId = new javax.swing.JLabel();
		bookIdText = new javax.swing.JTextField();
		restoreOldTextBtn = new javax.swing.JButton();
		advancedPanel = new javax.swing.JPanel();
		autoformatCb = new javax.swing.JCheckBox();
		lblCharset = new javax.swing.JLabel();
		partSizeText = new javax.swing.JTextField();
		lblBufferSize = new javax.swing.JLabel();
		charsetCombo = new javax.swing.JComboBox();
		advancedCb = new javax.swing.JCheckBox();
		rightToLeftCb = new javax.swing.JCheckBox();
		boooksPanel = new javax.swing.JPanel();
		jScrollPane1 = new javax.swing.JScrollPane();
		bookList = new javax.swing.JList();
		addBtn = new javax.swing.JButton();
		deleteBtn = new javax.swing.JButton();
		upBtn = new javax.swing.JButton();
		downBtn = new javax.swing.JButton();
		libPanel = new javax.swing.JPanel();
		saveBtn = new javax.swing.JButton();
		lblOutFile = new javax.swing.JLabel();
		saveTextField = new javax.swing.JTextField();
		lblWelcomeScreen = new javax.swing.JLabel();
		outFileBtn = new javax.swing.JButton();
		splashBtn = new javax.swing.JButton();
		defaultSplashBtn = new javax.swing.JButton();
		jScrollPane4 = new javax.swing.JScrollPane();
		splashLabel = new javax.swing.JLabel();
		lblMidletName = new javax.swing.JLabel();
		tfdMidletName = new javax.swing.JTextField();
		outPanel = new javax.swing.JPanel();
		jScrollPane3 = new javax.swing.JScrollPane();
		logTextArea = new javax.swing.JTextArea();

		jMenu1.setText("File");

		jMenuItemOfSaveProfile.setText("SaveProfile");
		jMenuItemOfSaveProfile
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						jMenuItemOfSaveProfileActionPerformed(evt);
					}
				});
		jMenu1.add(jMenuItemOfSaveProfile);

		jMenuItemOfLoadProfile.setText("LoadProfile");
		jMenuItemOfLoadProfile
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						jMenuItemOfLoadProfileActionPerformed(evt);
					}
				});
		jMenu1.add(jMenuItemOfLoadProfile);

		jMenuBar1.add(jMenu1);

		jMenu2.setText("View");
		jMenuBar1.add(jMenu2);

		setLayout(new java.awt.GridBagLayout());

		detailsPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Details"));

		lblBookName.setText("Book name");

		bookName.setEnabled(false);
		bookName.addFocusListener(new java.awt.event.FocusAdapter() {
			public void focusLost(java.awt.event.FocusEvent evt) {
				bookNameChange(evt);
			}
		});

		description.setEnabled(false);
		description.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				descriptionActionPerformed(evt);
			}
		});

		lblDescription.setText("Description");

		lblText.setText("Text");

		bookTextArea.setColumns(20);
		bookTextArea.setLineWrap(true);
		bookTextArea.setRows(5);
		bookTextArea.setWrapStyleWord(true);
		bookTextArea.setEnabled(false);
		jScrollPaneOfBookText.setViewportView(bookTextArea);

		saveChangesBtn.setIcon(new javax.swing.ImageIcon(getClass()
				.getResource("/button_ok16.png"))); // NOI18N
		saveChangesBtn.setEnabled(false);
		saveChangesBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		saveChangesBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveChangesBtnActionPerformed(evt);
			}
		});

		fileButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/fileopen16.png"))); // NOI18N
		fileButton.setEnabled(false);
		fileButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
		fileButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				fileButtonActionPerformed(evt);
			}
		});

		lblBookId.setText("Book ID");

		bookIdText.setEnabled(false);
		bookIdText.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				bookIdTextActionPerformed(evt);
			}
		});
		bookIdText.addKeyListener(new java.awt.event.KeyAdapter() {
			public void keyTyped(java.awt.event.KeyEvent evt) {
				bookIdTextKeyTyped(evt);
			}
		});

		restoreOldTextBtn.setText("restore");
		restoreOldTextBtn.setEnabled(false);
		restoreOldTextBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		restoreOldTextBtn
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						restoreOldTextBtnActionPerformed(evt);
					}
				});

		org.jdesktop.layout.GroupLayout detailsPanelLayout = new org.jdesktop.layout.GroupLayout(
				detailsPanel);
		detailsPanel.setLayout(detailsPanelLayout);
		detailsPanelLayout
				.setHorizontalGroup(detailsPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								detailsPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.add(
												detailsPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.LEADING)
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				detailsPanelLayout
																						.createParallelGroup(
																								org.jdesktop.layout.GroupLayout.LEADING)
																						.add(
																								lblBookId,
																								org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																								70,
																								Short.MAX_VALUE)
																						.add(
																								lblBookName,
																								org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																								70,
																								Short.MAX_VALUE))
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED)
																		.add(
																				detailsPanelLayout
																						.createParallelGroup(
																								org.jdesktop.layout.GroupLayout.LEADING)
																						.add(
																								bookIdText,
																								org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																								130,
																								Short.MAX_VALUE)
																						.add(
																								bookName,
																								org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																								130,
																								Short.MAX_VALUE)))
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				lblDescription)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED)
																		.add(
																				description,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				134,
																				Short.MAX_VALUE))
														.add(
																jScrollPaneOfBookText,
																org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																204,
																Short.MAX_VALUE)
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				lblText)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED,
																				180,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				fileButton)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.UNRELATED)
																		.add(
																				saveChangesBtn)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.UNRELATED)
																		.add(
																				restoreOldTextBtn,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																				68,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
										.addContainerGap()));
		detailsPanelLayout
				.setVerticalGroup(detailsPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								detailsPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.add(
												detailsPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.CENTER)
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				lblBookName)
																		.add(
																				10,
																				10,
																				10)
																		.add(
																				lblBookId))
														.add(
																detailsPanelLayout
																		.createSequentialGroup()
																		.add(
																				bookName,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
																		.add(
																				6,
																				6,
																				6)
																		.add(
																				bookIdText,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																				22,
																				org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												detailsPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.CENTER)
														.add(lblDescription)
														.add(
																description,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.UNRELATED)
										.add(lblText)
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												jScrollPaneOfBookText,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
												150,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												detailsPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.LEADING)
														.add(
																detailsPanelLayout
																		.createParallelGroup(
																				org.jdesktop.layout.GroupLayout.LEADING,
																				false)
																		.add(
																				fileButton,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				Short.MAX_VALUE)
																		.add(
																				saveChangesBtn,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				Short.MAX_VALUE))
														.add(
																restoreOldTextBtn,
																org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																30,
																Short.MAX_VALUE))
										.addContainerGap()));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		add(detailsPanel, gridBagConstraints);

		advancedPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Advanced options"));

		autoformatCb.setSelected(true);
		autoformatCb.setText("Autoformat");
		autoformatCb.setBorder(javax.swing.BorderFactory.createEmptyBorder(0,
				0, 0, 0));
		autoformatCb.setEnabled(false);
		autoformatCb
				.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
		autoformatCb.setMargin(new java.awt.Insets(0, 0, 0, 0));
		autoformatCb.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				autoformatCbActionPerformed(evt);
			}
		});

		lblCharset.setText("Character encoding");
		lblCharset.setEnabled(false);

		partSizeText.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
		partSizeText.setText("3000");
		partSizeText.setEnabled(false);
		partSizeText.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				partSizeTextActionPerformed(evt);
			}
		});

		lblBufferSize.setText("Buffer size");
		lblBufferSize.setEnabled(false);

		charsetCombo.setModel(new javax.swing.DefaultComboBoxModel(
				new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
		charsetCombo.setEnabled(false);
		charsetCombo.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				charsetComboActionPerformed(evt);
			}
		});

		advancedCb.setText("Enable advanced options");
		advancedCb.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0,
				0, 0));
		advancedCb
				.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
		advancedCb.setMargin(new java.awt.Insets(0, 0, 0, 0));
		advancedCb.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				advancedCbActionPerformed(evt);
			}
		});

		rightToLeftCb.setText("Right to left text");
		rightToLeftCb.setBorder(javax.swing.BorderFactory.createEmptyBorder(0,
				0, 0, 0));
		rightToLeftCb.setEnabled(false);
		rightToLeftCb
				.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
		rightToLeftCb.setMargin(new java.awt.Insets(0, 0, 0, 0));

		org.jdesktop.layout.GroupLayout advancedPanelLayout = new org.jdesktop.layout.GroupLayout(
				advancedPanel);
		advancedPanel.setLayout(advancedPanelLayout);
		advancedPanelLayout
				.setHorizontalGroup(advancedPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								advancedPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.add(
												advancedPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.LEADING)
														.add(advancedCb).add(
																autoformatCb)
														.add(rightToLeftCb))
										.add(15, 15, 15)
										.add(
												advancedPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.LEADING)
														.add(
																advancedPanelLayout
																		.createSequentialGroup()
																		.add(
																				lblCharset)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED)
																		.add(
																				charsetCombo,
																				0,
																				62,
																				Short.MAX_VALUE))
														.add(
																advancedPanelLayout
																		.createSequentialGroup()
																		.add(
																				lblBufferSize)
																		.add(
																				48,
																				48,
																				48)
																		.add(
																				partSizeText,
																				org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																				60,
																				Short.MAX_VALUE)))
										.addContainerGap()));
		advancedPanelLayout
				.setVerticalGroup(advancedPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								advancedPanelLayout
										.createSequentialGroup()
										.add(advancedCb)
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												advancedPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.BASELINE)
														.add(autoformatCb)
														.add(lblBufferSize)
														.add(
																partSizeText,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												advancedPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.BASELINE)
														.add(rightToLeftCb)
														.add(lblCharset)
														.add(
																charsetCombo,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
																22,
																org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
										.addContainerGap(
												org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		add(advancedPanel, gridBagConstraints);

		boooksPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Books"));
		boooksPanel.setMinimumSize(new java.awt.Dimension(150, 0));
		boooksPanel.setPreferredSize(new java.awt.Dimension(150, 10));

		bookList
				.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
		bookList
				.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
					public void valueChanged(
							javax.swing.event.ListSelectionEvent evt) {
						bookListValueChanged(evt);
					}
				});
		jScrollPane1.setViewportView(bookList);

		addBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/filenew16.png"))); // NOI18N
		addBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		addBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				addBtnActionPerformed(evt);
			}
		});

		deleteBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/stop16.png"))); // NOI18N
		deleteBtn.setEnabled(false);
		deleteBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		deleteBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				deleteBtnActionPerformed(evt);
			}
		});

		upBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/up16.png"))); // NOI18N
		upBtn.setEnabled(false);
		upBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		upBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				upBtnActionPerformed(evt);
			}
		});

		downBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/down16.png"))); // NOI18N
		downBtn.setEnabled(false);
		downBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		downBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				downBtnActionPerformed(evt);
			}
		});

		org.jdesktop.layout.GroupLayout boooksPanelLayout = new org.jdesktop.layout.GroupLayout(
				boooksPanel);
		boooksPanel.setLayout(boooksPanelLayout);
		boooksPanelLayout
				.setHorizontalGroup(boooksPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								boooksPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.add(
												jScrollPane1,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
												85,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												org.jdesktop.layout.LayoutStyle.RELATED)
										.add(
												boooksPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.TRAILING)
														.add(
																boooksPanelLayout
																		.createParallelGroup(
																				org.jdesktop.layout.GroupLayout.LEADING)
																		.add(
																				boooksPanelLayout
																						.createParallelGroup(
																								org.jdesktop.layout.GroupLayout.TRAILING)
																						.add(
																								addBtn)
																						.add(
																								deleteBtn))
																		.add(
																				downBtn))
														.add(upBtn))
										.addContainerGap()));
		boooksPanelLayout
				.setVerticalGroup(boooksPanelLayout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(
								boooksPanelLayout
										.createSequentialGroup()
										.add(
												boooksPanelLayout
														.createParallelGroup(
																org.jdesktop.layout.GroupLayout.LEADING)
														.add(
																boooksPanelLayout
																		.createSequentialGroup()
																		.add(
																				addBtn)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED)
																		.add(
																				deleteBtn)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED,
																				191,
																				Short.MAX_VALUE)
																		.add(
																				upBtn)
																		.addPreferredGap(
																				org.jdesktop.layout.LayoutStyle.RELATED)
																		.add(
																				downBtn))
														.add(
																jScrollPane1,
																org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
																303,
																Short.MAX_VALUE))
										.addContainerGap()));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weighty = 1.0;
		add(boooksPanel, gridBagConstraints);

		libPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Library"));
		libPanel.setLayout(new java.awt.GridBagLayout());

		saveBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/package32.png"))); // NOI18N
		saveBtn.setText("Create JAR");
		saveBtn.setEnabled(false);
		saveBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveBtnActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(2, 5, 0, 0);
		libPanel.add(saveBtn, gridBagConstraints);

		lblOutFile.setText("Output file");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		libPanel.add(lblOutFile, gridBagConstraints);

		saveTextField.setBackground(java.awt.Color.red);
		saveTextField.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveTextFieldActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.weightx = 2.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
		libPanel.add(saveTextField, gridBagConstraints);

		lblWelcomeScreen.setText("Welcome screen");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		libPanel.add(lblWelcomeScreen, gridBagConstraints);

		outFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/fileopen16.png"))); // NOI18N
		outFileBtn.setText("Choose file");
		outFileBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		outFileBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				outFileBtnActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
		libPanel.add(outFileBtn, gridBagConstraints);

		splashBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/fileopen16.png"))); // NOI18N
		splashBtn.setText("Choose file");
		splashBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		splashBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				splashBtnActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(2, 5, 0, 0);
		libPanel.add(splashBtn, gridBagConstraints);

		defaultSplashBtn.setIcon(new javax.swing.ImageIcon(getClass()
				.getResource("/back16.png"))); // NOI18N
		defaultSplashBtn.setEnabled(false);
		defaultSplashBtn.setMargin(new java.awt.Insets(2, 2, 2, 2));
		defaultSplashBtn.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				defaultSplashBtnActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 3;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(2, 5, 0, 0);
		libPanel.add(defaultSplashBtn, gridBagConstraints);

		jScrollPane4.setBorder(null);

		splashLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/ebook.png"))); // NOI18N
		splashLabel.setToolTipText("Image will not be resized!");
		splashLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
		jScrollPane4.setViewportView(splashLabel);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.gridheight = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(2, 5, 0, 0);
		libPanel.add(jScrollPane4, gridBagConstraints);

		lblMidletName.setText("Midlet Name");
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
		libPanel.add(lblMidletName, gridBagConstraints);

		tfdMidletName.setPreferredSize(new java.awt.Dimension(50, 21));
		tfdMidletName.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				tfdMidletNameActionPerformed(evt);
			}
		});
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 2.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
		libPanel.add(tfdMidletName, gridBagConstraints);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		add(libPanel, gridBagConstraints);

		outPanel.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Output"));

		jScrollPane3.setEnabled(false);
		jScrollPane3.setName("logTextArea");

		logTextArea.setColumns(20);
		logTextArea.setEditable(false);
		logTextArea.setLineWrap(true);
		logTextArea.setRows(5);
		logTextArea.setWrapStyleWord(true);
		jScrollPane3.setViewportView(logTextArea);

		org.jdesktop.layout.GroupLayout outPanelLayout = new org.jdesktop.layout.GroupLayout(
				outPanel);
		outPanel.setLayout(outPanelLayout);
		outPanelLayout.setHorizontalGroup(outPanelLayout.createParallelGroup(
				org.jdesktop.layout.GroupLayout.LEADING).add(
				outPanelLayout.createSequentialGroup().addContainerGap().add(
						jScrollPane3,
						org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 344,
						Short.MAX_VALUE).addContainerGap()));
		outPanelLayout.setVerticalGroup(outPanelLayout.createParallelGroup(
				org.jdesktop.layout.GroupLayout.LEADING).add(
				outPanelLayout.createSequentialGroup().add(jScrollPane3,
						org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 29,
						Short.MAX_VALUE).addContainerGap()));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		add(outPanel, gridBagConstraints);
	}// </editor-fold>

	// GEN-END:initComponents

	private void tfdMidletNameActionPerformed(java.awt.event.ActionEvent evt) {
		// TODO add your handling code here:
	}

	private void saveTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
		// TODO add your handling code here:
	}

	private boolean bookIdAuto = true;

	private void bookIdTextKeyTyped(java.awt.event.KeyEvent evt) {
		System.out.println("in bookIdTextKeyTyped:");
		String tName = this.getCurBookName();
		if (null != tName) {
			String id = this.bookIdText.getText();
			String tmpId = Utils.createIdFromName(tName);
			this.bookIdAuto = id != null && id.equals(tmpId) ? true : false;
		}

	}

	private void bookIdTextActionPerformed(java.awt.event.ActionEvent evt) {
		System.out.println("in bookIdTextActionPerformed:");

	}

	private void restoreOldTextBtnActionPerformed(java.awt.event.ActionEvent evt) {
		if (this.oldText != null
				&& !this.oldText.equals(this.bookTextArea.getText())) {
			this.bookTextArea.setText(this.oldText);
		}
		restoreOldTextBtn.setEnabled(false);
	}

	private void charsetComboActionPerformed(java.awt.event.ActionEvent evt) {
		File selectedFile = fOpenFileChooser.getSelectedFile();
		System.out.println("charsetComboActionPerformed:" + selectedFile);
		if (null != selectedFile && selectedFile.isFile()) {
			readText(selectedFile);

		}
	}

	private void jMenuItemOfLoadProfileActionPerformed(
			java.awt.event.ActionEvent evt) {
		int tmpRetVal = fProfileChooser.showOpenDialog(this);
		if (tmpRetVal == JFileChooser.APPROVE_OPTION) {
			final File tmpFile = fProfileChooser.getSelectedFile();
			String tmpPath = tmpFile.getPath();

			if (Utils.INFO) {
				Utils.info("save profile to path:" + tmpPath);
			}

			try {
				InputStream input = new FileInputStream(tmpPath);
				ProfileBean p = (ProfileBean) ProfileBean.read(input);
				this.loadProfile(p);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	private void jMenuItemOfSaveProfileActionPerformed(
			java.awt.event.ActionEvent evt) {
		int tmpRetVal = fProfileChooser.showSaveDialog(this);
		if (tmpRetVal == JFileChooser.APPROVE_OPTION) {
			final File tmpFile = fProfileChooser.getSelectedFile();
			saveProfile(tmpFile);

		}

	}

	private void saveProfile(final File tmpFile) {
		String tmpPath = tmpFile.getPath();
		if (!tmpPath.toLowerCase().endsWith(".xml")) {
			tmpPath = tmpPath + ".xml";
		}
		try {
			if (Utils.INFO) {
				Utils.info("load profile from path:" + tmpPath);
			}
			FileOutputStream output = new FileOutputStream(tmpPath);

			ProfileBean profileBean = this.getProfileBean();

			ProfileBean.write(profileBean, output);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void descriptionActionPerformed(java.awt.event.ActionEvent evt) {
		// TODO add your handling code here:
	}

	private void bookNameChange(AWTEvent evt) {
		// System.out.println("in bookNameFocusLost event:" + evt);
		String tName = this.getCurBookName();
		if (null != tName) {
			// System.out.println("bookId:" + tmpId);
			if (bookIdAuto || !this.isValidId(this.bookIdText.getText())) {
				String tmpId = Utils.createIdFromName(tName);
				this.bookIdText.setText(tmpId);
				this.bookIdAuto = true;
			}
		}

	}

	private String getCurBookName() {
		return this.bookName != null ? this.bookName.getText() : null;
	}

	// private void bookNameInputMethodTextChanged(
	// java.awt.event.InputMethodEvent evt) {
	// System.out.println("in bookNameInputMethodTextChanged");
	// if (this.bookName != null) {
	// String tName = this.bookName.getName();
	// if (null != tName) {
	// String tmpId = Utils.createIdFromName(tName);
	// System.out.println("bookId:" + tmpId);
	// if (this.bookIdText != null) {
	// this.bookIdText.setText(tmpId);
	// }
	// }
	// }
	// }

	private void partSizeTextActionPerformed(java.awt.event.ActionEvent evt) {
		// TODO add your handling code here:
	}

	private void downBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_downBtnActionPerformed
		setBookPos(bookList.getSelectedIndex() + 1);
	}// GEN-LAST:event_downBtnActionPerformed

	private void upBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_upBtnActionPerformed
		setBookPos(bookList.getSelectedIndex() - 1);
	}// GEN-LAST:event_upBtnActionPerformed

	private void setBookPos(int i) {
		bookListListenerEnabled = false;
		int idx = bookList.getSelectedIndex();
		bookChanged = false;
		Book tmpBook = (Book) listModel.remove(idx);
		listModel.add(i, tmpBook);
		oldIdx = i;
		bookList.setSelectedIndex(oldIdx);
		bookListListenerEnabled = true;
		downBtn.setEnabled(oldIdx > -1 && listModel.getSize() - 1 > oldIdx);
		upBtn.setEnabled(oldIdx > 0);
	}

	private void checkChangesInBook() {
		if (bookChanged
				&& oldIdx > -1
				&& JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(
						this, res.get("gui.confirm.savechanged"), res
								.get("gui.confirm.title"),
						JOptionPane.YES_NO_OPTION)) {
			saveBook();
		}
	}

	public ProfileBean getProfileBean() {
		ProfileBean p = new ProfileBean();
		j2me.util.List list = new j2me.util.ArrayList();
		for (int i = 0, n = listModel.size(); i < n; i++) {
			list.add((Book) listModel.get(i));
		}
		p.setMidletName(tfdMidletName.getText());
		p.setBooks(list);

		p.setJadPath(saveTextField.getText());

		return p;
	}

	protected void loadProfile(ProfileBean p) {
		this.idSet.clear();
		this.listModel.clear();
		List books = p.getBooks();
		if (null != books) {
			for (int i = 0; i < books.size(); i++) {
				Book b = (Book) books.get(i);
				listModel.addElement(b);
				idSet.add(b.getId());
			}
		}
		this.tfdMidletName.setText(p.getMidletName());
		final int size = listModel.size();
		if (size > 0) {
			bookList.setSelectedIndex(size - 1);
		}
		String jadPath = p.getJadPath();
		if (null != jadPath && jadPath.length() > 0) {
			saveTextField.setText(jadPath);
			fJadFileChooser.setSelectedFile(new File(jadPath));
		}

	}

	protected void runPackager() {
		saveBtn.setEnabled(false);
		checkChangesInBook();

		try {

			ProfileBean profile = this.getProfileBean();
			if (profile.getBookCount() == 0) {
				alert(res.get("gui.alert.notext"));
				return;
			}
			final List books = profile.getBooks();
			final Packager packager = new Packager();
			for (int i = 0, n = books.size(); i < n; i++) {
				packager.addBook((Book) books.get(i));
			}

			packager.setMidletName(profile.getMidletName());

			String outPrefix = profile.getJadPath();
			if (outPrefix == null || outPrefix.trim() == "") {
				alert(res.get("gui.alert.nooutput"));
				return;
			}
			outPrefix = ProfileBean.getOutPrefix(outPrefix);
			props.setProperty(Constants.PROP_OUT, outPrefix);

			logStream.println("----------------------");
			logStream.println(res.get("gui.log.genstarted"));

			packager.createSuite(logStream);

			logStream.println(res.get("gui.log.genfinished"));
			runEmulator();
		} catch (Exception e) {
			alert(res.get("gui.alert.err", new String[] { e.getMessage() }));
			e.printStackTrace(logStream);
			logStream.flush();
		}
		saveBtn.setEnabled(true);
	}

	protected void addBook() {
		int tmpPartSize = props.getAsInt(Constants.PROP_PARTSIZE);
		try {
			tmpPartSize = Integer.parseInt(partSizeText.getText());
		} catch (NumberFormatException e) {
			alert(res.get("gui.alert.partsize", new String[] { String
					.valueOf(tmpPartSize) }));
			partSizeText.setText(String.valueOf(tmpPartSize));
		}
		final Book tmpBook = new Book("Book " + (bookNr++), "Description",
				tmpPartSize);
		while (idSet.contains(tmpBook.getId())) {
			tmpBook.setName("Book " + (bookNr++));
		}
		tmpBook.setRightToLeft(rightToLeftCb.isSelected());
		idSet.add(tmpBook.getId());
		listModel.addElement(tmpBook);
		bookList.setSelectedIndex(listModel.size() - 1);
		checkSaveBtn();
	}

	protected void openBookFile(final File tmpFile) {
		try {
			readText(tmpFile);
			description.setText(null);
		} catch (Exception e) {
			alert(e.getMessage());
		}
	}

	private void readText(final File tmpFile) {
		this.oldText = bookTextArea.getText();

		this.restoreOldTextBtn.setEnabled(true);

		Book book = new Book();
		book.readText(tmpFile.getPath(), charsetCombo.getSelectedItem()
				.toString());
		String text = book.getText();
		bookTextArea.setText(text);

	}

	public void clearBookSelection() {
		bookList.clearSelection();
	}

	private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_saveBtnActionPerformed
		new Thread(new Runnable() {
			public void run() {
				runPackager();
			}
		}).start();
	}// GEN-LAST:event_saveBtnActionPerformed

	private String oldText = null;

	private boolean isValidId(String id) {
		return id != null && id.matches("^[a-zA-Z1-9_]+$");
	}

	protected void saveBook() {

		final Book tmpBook = (Book) listModel.getElementAt(oldIdx);
		if (saveChangesBtn.isEnabled()) {
			tmpBook.setName(bookName.getText());
			// tmpBook.setId(this.bookIdText.getText());
		}

		tmpBook.setDescription(description.getText());
		String text = this.bookIdText.getText();
		if (isValidId(text)) {
			tmpBook.setId(text);
		}

		tmpBook.setTextWithoutChange(bookTextArea.getText());
		tmpBook.setRightToLeft(rightToLeftCb.isSelected());
		File selectedFile = this.fOpenFileChooser.getSelectedFile();
		if (null != selectedFile) {
			tmpBook.setFilepath(selectedFile.getAbsolutePath());
		}
		listModel.setElementAt(tmpBook, oldIdx);
		idSet.remove(bookId);
		bookId = tmpBook.getId();
		idSet.add(bookId);
		bookChanged = false;
		oldText = null;
		bookIdAuto = true;
		detailsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.details")));
		saveChangesBtn.setEnabled(false);
	}

	private void saveChangesBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_saveChangesBtnActionPerformed
		saveBook();
	}// GEN-LAST:event_saveChangesBtnActionPerformed

	private void checkSaveBtn() {
		saveBtn.setEnabled(listModel.size() > 0
				&& saveTextField.getText().length() > 0);
	}

	private void deleteBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_deleteBtnActionPerformed
		int idx = bookList.getSelectedIndex();
		bookChanged = false;
		Book tmpBook = (Book) listModel.remove(idx);
		oldIdx = -1;
		idSet.remove(tmpBook.getId());

		int size = listModel.getSize();

		if (size > 0) {
			if (idx == listModel.getSize()) {
				// removed item in last position
				idx--;
			}

			bookList.setSelectedIndex(idx);
			bookList.ensureIndexIsVisible(idx);
		}
		checkSaveBtn();
	}// GEN-LAST:event_deleteBtnActionPerformed

	private void bookListValueChanged(javax.swing.event.ListSelectionEvent evt) {// GEN-FIRST:event_bookListValueChanged
		checkChangesInBook();
		oldIdx = bookList.getSelectedIndex();
		downBtn.setEnabled(oldIdx > -1 && listModel.getSize() - 1 > oldIdx);
		upBtn.setEnabled(oldIdx > 0);
		final boolean tmpEnabled = oldIdx > -1;
		if (tmpEnabled) {
			final Book tmpBook = (Book) listModel.getElementAt(oldIdx);
			bookId = tmpBook.getId();
			bookName.setText(tmpBook.getName());
			bookIdText.setText(tmpBook.getId());
			description.setText(tmpBook.getDescription());
			bookTextArea.setText(tmpBook.getText());
			if (tmpBook.getFilepath() != null) {
				fOpenFileChooser
						.setSelectedFile(new File(tmpBook.getFilepath()));
			}
		} else {
			bookName.setText("");
			bookIdText.setText("");
			description.setText("");
			bookTextArea.setText("");
			bookId = null;
		}
		bookName.setBackground(description.getBackground());
		bookIdText.setBackground(description.getBackground());
		bookChanged = false;
		detailsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(res
				.get("gui.panel.details")));
		bookName.setEnabled(tmpEnabled);
		bookIdText.setEnabled(tmpEnabled);
		description.setEnabled(tmpEnabled);
		bookTextArea.setEnabled(tmpEnabled);
		fileButton.setEnabled(tmpEnabled);
		saveChangesBtn.setEnabled(false);
		deleteBtn.setEnabled(tmpEnabled);
	}// GEN-LAST:event_bookListValueChanged

	private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_addBtnActionPerformed
		addBook();
	}// GEN-LAST:event_addBtnActionPerformed

	private void autoformatCbActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_autoformatCbActionPerformed
		props.setProperty(Constants.PROP_AUTOFORMAT, String
				.valueOf(autoformatCb.isSelected()));
	}// GEN-LAST:event_autoformatCbActionPerformed

	private void defaultSplashBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_defaultSplashBtnActionPerformed
		splashLabel
				.setIcon(new ImageIcon(getClass().getResource("/ebook.png")));
		defaultSplashBtn.setEnabled(false);
	}// GEN-LAST:event_defaultSplashBtnActionPerformed

	private void outFileBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_outFileBtnActionPerformed
		int tmpRetVal = fJadFileChooser.showSaveDialog(this);
		if (tmpRetVal == JFileChooser.APPROVE_OPTION) {
			final File tmpFile = fJadFileChooser.getSelectedFile();
			String tmpPath = tmpFile.getPath();
			if (!tmpPath.toUpperCase().endsWith(".JAD")) {
				tmpPath = tmpPath + ".jad";
			}
			saveTextField.setText(tmpPath);

			tfdMidletName.setText(ProfileBean.generatedMidletName(tmpPath));

		}
	}// GEN-LAST:event_outFileBtnActionPerformed

	private void splashBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_splashBtnActionPerformed
		File tmpFile = imageChooser.openImageFile(this);
		if (tmpFile != null) {
			splashLabel.setIcon(new ImageIcon(tmpFile.getAbsolutePath()));
			defaultSplashBtn.setEnabled(true);
			props.setProperty(Constants.PROP_SPLASH, tmpFile.getAbsolutePath());
		}
	}// GEN-LAST:event_splashBtnActionPerformed

	private void fileButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_fileButtonActionPerformed
		int tmpRetVal = fOpenFileChooser.showOpenDialog(this);
		if (tmpRetVal == JFileChooser.APPROVE_OPTION) {
			try {
				openBookFile(fOpenFileChooser.getSelectedFile());
			} catch (Exception e) {
				alert(e.getMessage());
			}
		}
	}// GEN-LAST:event_fileButtonActionPerformed

	private void advancedCbActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_advancedCbActionPerformed
		setAdvancedEnabled();
	}// GEN-LAST:event_advancedCbActionPerformed

	// GEN-BEGIN:variables
	// Variables declaration - do not modify
	private javax.swing.JButton addBtn;
	private javax.swing.JCheckBox advancedCb;
	private javax.swing.JPanel advancedPanel;
	private javax.swing.JCheckBox autoformatCb;
	private javax.swing.JTextField bookIdText;
	private javax.swing.JList bookList;
	private javax.swing.JTextField bookName;
	private javax.swing.JTextArea bookTextArea;
	private javax.swing.JPanel boooksPanel;
	private javax.swing.JComboBox charsetCombo;
	private javax.swing.JButton defaultSplashBtn;
	private javax.swing.JButton deleteBtn;
	private javax.swing.JTextField description;
	private javax.swing.JPanel detailsPanel;
	private javax.swing.JButton downBtn;
	private javax.swing.JButton fileButton;
	private javax.swing.JMenu jMenu1;
	private javax.swing.JMenu jMenu2;
	private javax.swing.JMenuBar jMenuBar1;
	private javax.swing.JMenuItem jMenuItemOfLoadProfile;
	private javax.swing.JMenuItem jMenuItemOfSaveProfile;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JScrollPane jScrollPane3;
	private javax.swing.JScrollPane jScrollPane4;
	private javax.swing.JScrollPane jScrollPaneOfBookText;
	private javax.swing.JLabel lblBookId;
	private javax.swing.JLabel lblBookName;
	private javax.swing.JLabel lblBufferSize;
	private javax.swing.JLabel lblCharset;
	private javax.swing.JLabel lblDescription;
	private javax.swing.JLabel lblMidletName;
	private javax.swing.JLabel lblOutFile;
	private javax.swing.JLabel lblText;
	private javax.swing.JLabel lblWelcomeScreen;
	private javax.swing.JPanel libPanel;
	private javax.swing.JTextArea logTextArea;
	private javax.swing.JButton outFileBtn;
	private javax.swing.JPanel outPanel;
	private javax.swing.JTextField partSizeText;
	private javax.swing.JButton restoreOldTextBtn;
	private javax.swing.JCheckBox rightToLeftCb;
	private javax.swing.JButton saveBtn;
	private javax.swing.JButton saveChangesBtn;
	private javax.swing.JTextField saveTextField;
	private javax.swing.JButton splashBtn;
	private javax.swing.JLabel splashLabel;
	private javax.swing.JTextField tfdMidletName;
	private javax.swing.JButton upBtn;

	// End of variables declaration//GEN-END:variables

	public javax.swing.JMenuBar getJMenuBar() {
		return jMenuBar1;
	}

}

/**
 * OutputStream wrapper for writing to JTextArea component
 *
 * @author Josef Cacek
 */
class JTextAreaStream extends OutputStream {
	protected JTextArea textArea;

	protected ByteArrayOutputStream baos;

	public JTextAreaStream(JTextArea textArea) {
		this.textArea = textArea;
		this.baos = new ByteArrayOutputStream();
	}

	public void write(int c) {
		this.baos.write((char) c);
		this.update();
	}

	public void write(byte[] bytes, int offset, int length) {
		this.baos.write(bytes, offset, length);
		this.update();
	}

	protected void update() {
		String text = new String(this.baos.toByteArray());
		this.textArea.setText(text);
		this.textArea.setCaretPosition(text.length());
	}

}